<template>
  <div class="wrapper">
    <ActionBar
      ref="actionBar"
      :options="actionBarData"
      @btnClick="actionClick"
    />
    <div class="main">
      <!-- 顶部搜索框 -->
      <div class="search-box">
        <slot name="search-box"></slot>
        <img
          src="~@/assets/action-bar-icon/search.png"
          class="search-btn"
          @click="search"
        />
      </div>
      <!-- 底部表格和表单 -->
      <div class="container">
        <div class="table-wrap" :style="{ flex: tableWidth }">
          <el-table
            ref="table"
            v-loading="!tableData.length"
            :data="tableData"
            :highlight-current-row="highlightCurrentRow"
            stripe
            border
            height="90%"
            @row-click="rowClick"
            @selection-change="changeSelection"
          >
            <slot name="left-table-column-wrap"></slot>
          </el-table>
          <Pagination
            :total-size="totalPageSize"
            :page-size="size"
            :current-page="page"
            @changePageSize="changeSize"
            @changeCurrentPage="changePage"
          />
        </div>
        <div class="form-wrap" :style="{ flex: formWidth }">
          <el-form
            ref="form"
            :model="formData"
            :rules="formRules"
            label-position="left"
            label-width="100px"
            :disabled="!state"
          >
            <slot name="right-form-item-wrap"></slot>
          </el-form>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import ActionBar from "./ActionBar";
import Pagination from "@/components/Pagination";

export default {
  name: "Wrapper",
  components: {
    ActionBar,
    Pagination
  },
  props: {
    // 必须将绑定给表格、表单的数据传递过来。表单可以附加验证规则
    tableData: {
      type: Array,
      required: true
    },
    formData: {
      type: Object,
      required: true
    },
    formRules: {
      type: Object,
      default: () => ({})
    },

    // 调整表格和表单区域的宽度
    tableWidth: {
      type: Number,
      default: 1.5
    },
    formWidth: {
      type: Number,
      default: 1
    },

    // 分页器
    totalPageSize: {
      type: [String, Number],
      default: 0
    },
    size: {
      type: [String, Number],
      default: 10
    },
    page: {
      type: [String, Number],
      default: 1
    }
  },
  data() {
    return {
      form: null,
      table: null,
      curRowData: null,
      selectionList: [],

      state: "" // 记录现在是添加还是修改
    };
  },
  computed: {
    actionBarData() {
      return {
        add: !this.state && !this.selectionList.length,
        edit: this.curRowData && !this.state && this.highlightCurrentRow,
        del: this.selectionList.length,
        save: this.state,
        cancel: this.state || this.selectionList.length
      };
    },
    highlightCurrentRow() {
      return !this.selectionList.length && this.state !== "adding";
    }
  },
  mounted() {
    this.form = this.$refs.form;
    this.table = this.$refs.table;
  },
  methods: {
    actionClick({ type }) {
      const eventData = {
        type,
        data: {},
        form: this.form,
        table: this.table,
        originType: "",
        resetBtn: () => (this.state = "")
      };
      switch (type) {
        case "add":
          this.state = "adding";
          this.reset();
          break;
        case "cancel":
          eventData.originType = this.state;
          this.state = "";
          this.table.setCurrentRow(this.curRowData);
          this.table.clearSelection();
          break;
        case "edit":
          this.state = "modify";
          break;
        case "del":
          eventData.data = this.selectionList;
          break;
        case "save":
          eventData.type = this.state;
          break;
      }
      this.$emit("clickBtn", eventData);
    },

    reset() {
      this.curRowData = null;
      this.table.setCurrentRow();
      this.table.clearSelection();
    },

    search() {
      this.$emit("search");
    },
    changeSize(size) {
      this.$emit("getTableDataList", {
        page: this.page,
        size
      });
    },
    changePage(page) {
      this.$emit("getTableDataList", {
        page,
        size: this.size
      });
    },

    rowClick(row) {
      if (this.state === "modify") {
        return this.table.setCurrentRow(this.curRowData);
      }
      if (this.highlightCurrentRow) {
        this.curRowData = row;
        this.$emit("clickRow", row);
      }
    },
    changeSelection(selection) {
      if (this.state) {
        return this.table.clearSelection();
      }
      if (!selection.length) {
        this.table.setCurrentRow(this.curRowData);
      }
      this.selectionList = selection;
      this.$emit("changeSelection", selection);
    }
  }
};
</script>

<style lang="scss" scoped>
@import "~@/styles/variables.scss";
.wrapper {
  width: 100%;
  height: 100%;
  user-select: none;
  .main {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    height: calc(100% - 60px);
    border: 1px solid $borderColor;
    padding: 20px;
    box-sizing: border-box;

    .search-box,
    .container {
      width: 100%;
    }

    .search-box {
      display: flex;
      align-items: center;
      height: 36px;
      line-height: 36px;
      margin-bottom: 20px;
      img.search-btn {
        height: 30px;
        cursor: pointer;
        margin-left: 20px;
        order: 999;
      }
    }
    .container {
      display: flex;
      height: calc(100% - 36px - 20px);
      .pagination {
        bottom: 0;
      }
      .table-wrap,
      .form-wrap {
        height: 100%;
        position: relative;
        overflow-y: auto;
      }
      .form-wrap {
        padding-left: 15px;
        margin-left: 15px;
        border-left: 1px dashed $borderColor;
        ::v-deep .el-form-item__label {
          text-align: right;
        }
      }
    }
  }
}
</style>
